﻿using ST.Common.Util.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;

namespace ST.Common.Util.Text
{
	/// <summary>
	/// 身份证号相关
	/// </summary>
	public class IDCardHelper
	{
		/// <summary>
		/// 获取新版18位身份证号最后一位校验位
		/// </summary>
		/// <param name="idcardno"></param>
		/// <returns></returns>
		public static char GetIDCardNoCRC(string idcardno)
		{
			if (string.IsNullOrEmpty(idcardno) || !new Regex("^\\d{17}[\\dxX]?$").IsMatch(idcardno))
			{
				throw new ArgumentException("身份证格式有误");
			}
			char[] crcCode = new char[] { '1', '0', 'x', '9', '8', '7', '6', '5', '4', '3', '2' };
			int[] Wi = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
			int sum = 0;
			for (int i = 0; i < 17; i++)
			{
				sum += Wi[i] * int.Parse(idcardno[i].ToString());
			}
			return crcCode[sum % 11];
		}

		/// <summary>
		/// 校验18位身份证号码
		/// </summary>
		/// <param name="idcardno"></param>
		/// <returns></returns>
		public static bool CheckIDCardNo18(string idcardno)
		{
			try
			{
				if (string.IsNullOrEmpty(idcardno) || idcardno.Length != 18)
				{
					return false;
				}
				string prefix = "11:北京,12:天津,13:河北,14:山西,15:内蒙,21:辽宁,22:吉林,23:黑龙江,31:上海,32:江苏,33:浙江,34:安徽,35:福建,36:江西,37:山东,41:河南,42:湖北,43:湖南,44:广东,45:广西,46:xx,50:xx,51:四川,52:贵州,53:云南,54:西藏,61:陕西,62:甘肃,63:青海,64:宁夏,65:新疆,71:xx,81:xx,82:xx,91:xx";
				if (prefix.IndexOf(idcardno.Substring(0, 2)) == -1)
				{
					return false;//省份验证
				}
				DateTime dt;
				if (!DateTime.TryParseExact(idcardno.Substring(6, 8), "yyyyMMdd", null, DateTimeStyles.None, out dt))
				{
					return false;//出生日期校验
				}
				char crc = GetIDCardNoCRC(idcardno);
				return idcardno[17] == crc || (crc == 'x' && idcardno[17] == 'X');
			}
			catch
			{
				return false;
			}
		}

		public static IDCardNoInfo ParseIDCardNo18(string idcardno)
		{
			IDCardNoInfo info = null;
			try
			{
				if (string.IsNullOrEmpty(idcardno) || idcardno.Length != 18)
				{
					throw new ArgumentException("身份证长度有误");
				}
				string prefix = "11:北京,12:天津,13:河北,14:山西,15:内蒙,21:辽宁,22:吉林,23:黑龙江,31:上海,32:江苏,33:浙江,34:安徽,35:福建,36:江西,37:山东,41:河南,42:湖北,43:湖南,44:广东,45:广西,46:xx,50:xx,51:四川,52:贵州,53:云南,54:西藏,61:陕西,62:甘肃,63:青海,64:宁夏,65:新疆,71:xx,81:xx,82:xx,91:xx";
				if (prefix.IndexOf(idcardno.Substring(0, 2)) == -1)
				{
					throw new ArgumentException("身份证前1-2位省代码有误");//
				}
				DateTime dt;
				if (!DateTime.TryParseExact(idcardno.Substring(6, 8), "yyyyMMdd", null, DateTimeStyles.None, out dt))
				{
					throw new ArgumentException("身份证出生日期有误");//出生日期校验
				}
				char crc = GetIDCardNoCRC(idcardno);
				if (idcardno[17] == crc || (crc == 'x' && idcardno[17] == 'X'))
				{
					info = new IDCardNoInfo();
					info.BirthDate = dt;
					info.Male = int.Parse(idcardno.Substring(14, 3)) % 2 != 0;
				}
				else
				{
					throw new ArgumentException("身份证校验码有误");
				}
				return info;
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}
	}
}
